#pragma once

#include <iostream>
#include <ostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "iroperand.h"

struct SideEffect {
    bool io = false;
    std::unordered_map<std::string, IR::Variable> var;
    std::unordered_map<std::string, IR::Variable> mem;

    void Clear() { var.clear(), mem.clear(); }
    bool Empty() { return var.empty() && mem.empty(); }

    void AddVar(IR::Variable* v) { var[v->name] = *v; }
    void AddMem(IR::Variable* ptr) { mem[ptr->memBase->name] = *ptr->memBase; }

    void Merge(const SideEffect& other) {
        var.insert(other.var.begin(), other.var.end());
        mem.insert(other.mem.begin(), other.mem.end());
        io |= other.io;
    }

    void Print() {
        std::cout << DEF "Var: ";
        for (auto [_, x] : var) {
            x.Print(), std::cout << " ";
        }
        std::cout << DEF "\nMem: ";
        for (auto [_, x] : mem) {
            x.Print(), std::cout << " ";
        }
        std::cout << "\n";
    }
};
